package thinkingInJava.generics.SelfBound;
// page 406 自限定 用于保证类型参数必须与正在定义的类形同.
//: generics/SelfBounding.java

class SelfBounded<T extends SelfBounded<T>> {
T element;
SelfBounded<T> set(T arg) {
  element = arg;
  return this;
}
T get() { return element; }
}

class A extends SelfBounded<A> {}
class B extends SelfBounded<A> {} // Also OK

class C extends SelfBounded<C> {
C setAndGet(C arg) { set(arg); return get(); }
}	

class D {}
//Can't do this:
//class E extends SelfBounded<D> {}
//Compile error: Type parameter D is not within its bound

//Alas, you can do this, so you can't force the idiom:
class F extends SelfBounded {}

class SelfBounded2<T extends SelfBounded2<T>> {
T element;
SelfBounded2<T> set(T arg) {
  element = arg;
  return this;
}
T get() { return element; }
}
class O extends SelfBounded2{}

public class SelfBounding {
public static void main(String[] args) {
  A a = new A();
  a.set(new A());
  a = a.set(new A()).get();
  a = a.get();
  C c = new C();
  c = c.setAndGet(new C());
  F f = new F();
  f.set(f);
  f.set(a);
//  f.set(new O());
}
} ///:~
